from typing import Generic, TypeVar, Optional, Any, List, Dict
from pydantic import BaseModel, Field
from enum import Enum

# 泛型类型变量
T = TypeVar('T')

class ResponseStatus(str, Enum):
    """响应状态枚举"""
    SUCCESS = "success"
    ERROR = "error"
    WARNING = "warning"

class ErrorCode(str, Enum):
    """错误代码枚举"""
    # 通用错误
    VALIDATION_ERROR = "VALIDATION_ERROR"
    AUTHENTICATION_FAILED = "AUTHENTICATION_FAILED"
    AUTHORIZATION_FAILED = "AUTHORIZATION_FAILED"
    RESOURCE_NOT_FOUND = "RESOURCE_NOT_FOUND"
    INTERNAL_SERVER_ERROR = "INTERNAL_SERVER_ERROR"
    
    # 业务错误
    INVALID_DATE_FORMAT = "INVALID_DATE_FORMAT"
    DATA_NOT_FOUND = "DATA_NOT_FOUND"
    PREDICTION_FAILED = "PREDICTION_FAILED"
    USER_ALREADY_EXISTS = "USER_ALREADY_EXISTS"
    INVALID_CREDENTIALS = "INVALID_CREDENTIALS"

class BaseResponse(BaseModel, Generic[T]):
    """统一响应基类"""
    status: ResponseStatus = Field(description="响应状态")
    message: str = Field(description="响应消息")
    data: Optional[T] = Field(default=None, description="响应数据")
    error_code: Optional[ErrorCode] = Field(default=None, description="错误代码")
    timestamp: Optional[str] = Field(default=None, description="响应时间戳")

class SuccessResponse(BaseResponse[T]):
    """成功响应"""
    status: ResponseStatus = ResponseStatus.SUCCESS
    
    @classmethod
    def create(cls, data: T, message: str = "操作成功") -> "SuccessResponse[T]":
        from datetime import datetime
        return cls(
            status=ResponseStatus.SUCCESS,
            message=message,
            data=data,
            timestamp=datetime.now().isoformat()
        )

class ErrorResponse(BaseResponse[None]):
    """错误响应"""
    status: ResponseStatus = ResponseStatus.ERROR
    data: None = None
    
    @classmethod
    def create(cls, message: str, error_code: ErrorCode, details: Optional[Dict[str, Any]] = None) -> "ErrorResponse":
        from datetime import datetime
        return cls(
            status=ResponseStatus.ERROR,
            message=message,
            error_code=error_code,
            timestamp=datetime.now().isoformat()
        )

class PaginationMeta(BaseModel):
    """分页元数据"""
    page: int = Field(description="当前页码")
    size: int = Field(description="每页大小")
    total: int = Field(description="总数量")
    pages: int = Field(description="总页数")

class PaginatedResponse(BaseModel, Generic[T]):
    """分页响应"""
    items: List[T] = Field(description="数据列表")
    meta: PaginationMeta = Field(description="分页信息")

# 具体业务响应模型
class LoginData(BaseModel):
    """登录响应数据"""
    access_token: str = Field(description="访问令牌")
    token_type: str = Field(default="bearer", description="令牌类型")
    expires_in: int = Field(description="过期时间(秒)")
    user: Dict[str, Any] = Field(description="用户信息")

class UserInfo(BaseModel):
    """用户信息"""
    id: int = Field(description="用户ID")
    username: str = Field(description="用户名")
    role: str = Field(description="用户角色")
    created_at: Optional[str] = Field(default=None, description="创建时间")

class PredictionData(BaseModel):
    """预测数据响应"""
    date: str = Field(description="预测日期")
    date_formatted: str = Field(description="格式化日期")
    prediction_values: List[float] = Field(description="预测值列表")
    time_labels: List[str] = Field(description="时间标签")
    statistics: Dict[str, Any] = Field(description="统计信息")

class DateInfo(BaseModel):
    """日期信息"""
    value: str = Field(description="日期值")
    label: str = Field(description="日期标签")
    formatted: str = Field(description="格式化日期")

class AvailableDatesData(BaseModel):
    """可用日期数据"""
    dates: List[DateInfo] = Field(description="日期列表")
    count: int = Field(description="日期数量")
    start_date: Optional[str] = Field(description="开始日期")
    end_date: Optional[str] = Field(description="结束日期")

class HistoricalDataItem(BaseModel):
    """历史数据项"""
    date: str = Field(description="日期")
    value: str = Field(description="数值")
    data_type: str = Field(description="数据类型")

class StatisticsInfo(BaseModel):
    """统计信息"""
    total_energy: float = Field(description="总能耗")
    peak_load: float = Field(description="峰值负荷")
    valley_load: float = Field(description="谷值负荷")
    avg_load: float = Field(description="平均负荷")
    peak_valley_diff: float = Field(description="峰谷差")
    peak_valley_ratio: float = Field(description="峰谷比")
    load_factor: float = Field(description="负荷率")
    std_dev: float = Field(description="标准差")
    cv: float = Field(description="变异系数")
    peak_time: str = Field(description="峰值时间")
    valley_time: str = Field(description="谷值时间")
    data_points: int = Field(description="数据点数")

class MultiDayPredictionData(BaseModel):
    """多日预测数据响应"""
    start_date: str = Field(description="开始日期")
    end_date: str = Field(description="结束日期")
    day_count: int = Field(description="天数")
    predictions: List[Dict[str, Any]] = Field(description="预测数据列表")
    models_included: List[str] = Field(description="包含的模型列表")

class SingleDayPredictionData(BaseModel):
    """单日预测数据响应"""
    date: str = Field(description="预测日期")
    predictions: List[Dict[str, Any]] = Field(description="预测数据列表")

# 响应类型别名
LoginResponse = SuccessResponse[LoginData]
UserResponse = SuccessResponse[UserInfo]
PredictionResponse = SuccessResponse[PredictionData]
MultiDayPredictionResponse = SuccessResponse[MultiDayPredictionData]
SingleDayPredictionResponse = SuccessResponse[SingleDayPredictionData]
AvailableDatesResponse = SuccessResponse[AvailableDatesData]
HistoricalDataResponse = SuccessResponse[List[HistoricalDataItem]]
StatisticsResponse = SuccessResponse[StatisticsInfo] 